#! /usr/bin/env python
import os
import hashlib
import time
import subprocess
import simplejson
import urllib,urllib2
import pycurl
import StringIO
import sys
import datetime
from malware_inspector_config import config
from malware_inspector_config import sqlite_class

file_read_bytes = 8192

def md5checksum(filePath,config):
	"""compute MD5 checksum"""
	try:
		with open(filePath, 'rb') as f:
			m = hashlib.md5()
        		while True:
        	    		data = f.read(file_read_bytes)
        	    		if not data:
        	        		break
        	    		m.update(data)
			config.logger.debug("file - %s and its md5 hash value is %s" %(filePath,m.hexdigest())) 
        		return m.hexdigest()
	except Exception,e:
		config.logger.error("Error while calculating md5 hash for file - %s " %filePath)

def check_internet_connection(config):
	""" check if PC is connected to internet"""	
	url = 'http://www.google.com/'

	storage = StringIO()
	c = pycurl.Curl()
	if config.use_proxy:
		c.setopt(pycurl.PROXYTYPE,pycurl.PROXYTYPE_HTTP)
		c.setopt(pycurl.PROXY,config.proxy_name)
		c.setopt(pycurl.PROXYPORT,config.proxy_port)
		c.setopt(pycurl.PROXYUSERPWD,config.proxy_user + ":" + config.proxy_password)
	c.setopt(c.URL, url)
	c.setopt(c.WRITEFUNCTION, storage.write)
	c.perform()
	c.close()
	content = storage.getvalue()
	if content:
		return True
	else:
		return False

def process_status(pid):
	""" find process state"""
	"""	
		D Uninterruptible sleep (usually IO)
		R Running or runnable (on run queue)
		S Interruptible sleep (waiting for an event to complete)
		T Stopped, either by a job control signal or because it is being traced.
		W paging (not valid since the 2.6.xx kernel)
		X dead (should never be seen)
		Z Defunct ("zombie") process, terminated but not reaped by its parent.
	"""
	try:
		for line in open("/proc/%s/status" % pid).readlines():
			if line.startswith("State:"):
				return line.split(":",1)[1].strip().split(' ')[0]
		return None
	except Exception,e:
		config.logger.error("Error while reading process state for pid - " %pid)

def file_timestamps(filename):
	"""file creation and modification timestamps"""
	if os.path.isfile(filename):
		last_modified = time.ctime(os.path.getmtime(filename))
		created_on = time.ctime(os.path.getctime(filename))
		return created_on, last_modified
	
def run_command(exec_command, timeout=10, poll_seconds=0.25):
	""" run the command as a seperate process"""	
	try:
		proc = subprocess.Popen(exec_command, bufsize=0, shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE)
		deadline = time.time() + float(timeout)
		while time.time() < deadline and proc.poll() == None:
			time.sleep(float(poll_seconds))
		stdout, stderr = proc.communicate()
		return stdout, stderr
	except Exception,e:
		config.logger.error("Error while executing the command - %s"%exec_command)

def malware_check(md5_hash,config):
	""" query malware hash registry to check whether the process is malware"""
	try:
		_cmd = "nslookup -querytype=TXT " + md5_hash + '.' + config.team_cymru_url #'.malware.hash.cymru.com'
		response,error = run_command(_cmd,config.timeout_interval,config.polling_interval)
		config.logger.debug("Team Cymru malware hash registry response - %s" %response)
		return response,error
	except Exception,e:
		config.logger.error("Error while executing command - %s and the error is - %s"%(_cmd,e))

def malware_processes_using_team_cymru(config,process_list,sqlite_instance):
	""" find out malware processes using team cymru hash registry"""
	try:
		team_cymru_virus_process = []
		for item in process_list:
			#check if the process exists in database - process name and md5 hash are same or changed
			process_db_check = sqlite_instance.getrow("select id from malware_process where full_path = ? and md5_hash = ?",(item[1],item[3]))
			#print process_db_check
			# check if the process is previously checked using Team Cymru malware hash registry
			cymru_process_check = sqlite_instance.getrow("select id from malware_teamcymru_scan where process_id = ?",(process_db_check))
			#print cymru_process_check
			# if the process exists, a row will be returned. If no row is returned, insert present process into the database and do malware check.
			# check team cymru malware hash repository for process hash
			if not (process_db_check and cymru_process_check):
				process_name,process_path,process,md5_result,last_modified,process_state,filesize = item[5],item[4],item[1],item[3],item[8],item[6],item[2]
				#print process_name,process_path,process,md5_result,last_modified,process_state,filesize
				sqlite_instance.execute_query("insert into malware_process(name,base_path,full_path,md5_hash,insertion_date,process_state,file_size) values (?,?,?,?,?,?,?)",(process_name,process_path,process,md5_result,last_modified,process_state,filesize))
				config.logger.info("Executing the query - insert into malware_process(name,base_path,full_path,md5_hash,insertion_date,process_state,file_size) values (%s,%s,%s,%s,%s,%s,%s)"%(process_name,process_path,process,md5_result,last_modified,process_state,filesize))
				sqlite_instance.commit(True)						
				response,error = malware_check(item[3],config)
				# add delay of 1 sec for each TXT query to team cymru hash registry
				time.sleep(1)
				config.logger.debug("Team Cymru scan - process details - %s" %item[1])
				Ismalware,last_detected,percent_detection = process_team_cymru_response(item[3],response,config)
				if Ismalware:
					config.logger.info("Process -%s is possibly a virus/malware. Kindly re-check it using other anti-virus/anti-spyware softwares."%item[1])
					team_cymru_virus_process.append(item)
					# team cymru response contains  - when it was last seen and what is % that it will be detected by anti-virus softwares.
					# check if entry exists in teamcymru_scan table
					check_process = sqlite_instance.getrow("select id from malware_teamcymru_scan where process_id =?",(item[0]))
					if not check_process:
						sqlite_instance.execute_query("insert into malware_teamcymru_scan(last_seen,percent_detection,process_id,ismalware) values (?,?,?,?)",(last_detected,percent_detection,item[0],Ismalware))
						config.logger.info("Executing the query - insert into malware_teamcymru_scan(last_seen,percent_detection,process_id,ismalware) values (%s,%s,%s,%s)"%(last_detected,percent_detection,item[0],Ismalware)) 
			else:
				# the process is present in process table but it was not previously checked using Team Cymru's database. 
				# check if the process is malware and update entry
				response,error = malware_check(item[3],config)
				# add delay of 1 sec for each TXT query to team cymru hash registry
				time.sleep(1)
				config.logger.debug("Team Cymru scan - process details - %s" %item[1])
				Ismalware,last_detected,percent_detection = process_team_cymru_response(item[3],response,config)
				if Ismalware:
					config.logger.info("Process -%s is possibly a virus/malware. Kindly re-check it using other anti-virus/anti-spyware softwares."%item[1])
					team_cymru_virus_process.append(item)
					# update entry in team cymru table
					config.logger.info("Executing the query - update malware_teamcymru_scan set last_seen = ? percent_detection = ? ismalware = ? where process_id = ?"%(last_detected,percent_detection,Ismalware,process_db_check))
					sqlite_instance.execute_query("update malware_teamcymru_scan set last_seen = ? percent_detection = ? ismalware = ? where process_id = ?"%(last_detected,percent_detection,Ismalware,process_db_check))
					
		# return a list of malware processes
		return team_cymru_virus_process
	except Exception,e:
		config.logger.error("Error while finding out malware processes using Team Cymru - %s"%(e))

def process_team_cymru_response(md5_hash,response,config):
	try:
		response = response.split('\n')
		for item in response:
			if item.find( md5_hash + '.' + config.team_cymru_url)>=0:
				malware_line = item
				if malware_line.lower().find('nxdomain')>=0:
					return False,'','' # no malware present
				else:
					malware_details = malware_line.strip().split('=')[1]
					last_updated,percent_detection = malware_details.replace('"','').strip().split(' ')
					#print last_updated,percent_detection
					return True,datetime.datetime.fromtimestamp(long(last_updated)),percent_detection

	except Exception,e:
		config.logger.error("Error while processing Team Cymru's response - %s and the error is - %s"%(response,e))

def SetProxiesIfNecessary():
    if os.getenv('http_proxy') != None:
        dProxies['http'] = os.getenv('http_proxy')
    if os.getenv('https_proxy') != None:
        dProxies['https'] = os.getenv('https_proxy')
    if dProxies != {}:
        urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler(dProxies)))


def virustotal_search_urllib(md5_hash,api_key):
	SetProxiesIfNecessary()
	url = 'https://www.virustotal.com/vtapi/v2/file/report'
	parameters= {'resource':md5_hash,'apikey':api_key}
	data = urllib.urlencode(parameters)
	req = urllib2.Request(url,data)
	response = urllib2.urlopen(req)
	json = response.read()
	response_dict=simplejson.loads(json)


def curl_virustotal_search(md5_hash,api_key,virustotal_url,use_proxy,proxy_name,proxy_port,proxy_user,proxy_passwd):
	global output  
	output = StringIO.StringIO()
	c = pycurl.Curl()
	c.setopt(pycurl.FOLLOWLOCATION,1)
	c.setopt(c.POST,1)
	c.setopt(c.HTTPPOST,[('resource',md5_hash),('apikey',api_key)])
	c.setopt(c.URL,virustotal_url)
	if use_proxy:
		c.setopt(pycurl.PROXYTYPE,pycurl.PROXYTYPE_HTTP)
		c.setopt(pycurl.PROXY,proxy_name)
		c.setopt(pycurl.PROXYPORT,proxy_port)
		c.setopt(pycurl.PROXYUSERPWD,proxy_user + ":" + proxy_passwd)
	#c.setopt(c.VERBOSE, 1) # Need verbosity?
	#c.setopt(c.SSL_VERIFYPEER, 0)
	# For protected and private method
	#c.setopt(c.SSLCERT, "/home/psj/Certificate_files/usercert.pem")
	#c.setopt(c.SSLKEY, "/home/psj/Certificate_files/userkey.pem")
	#c.setopt(c.CAPATH, "/path/to/the/cacerts")
	#c.setopt(pycurl.VERBOSE,True)
	c.setopt(c.WRITEFUNCTION, output.write)
	c.perform()
	result = output.getvalue()
	c.close()
	response_dict = simplejson.loads(result)
	if response_dict['response_code']==0 or response_dict['response_code']==-1:
		Ismalware = False
	else:
		Ismalware = True	
	#if response_dict['response_code']==0:
	#	print "The file is not a malware as no result could be found in the virustotal database."
	#elif response_dict['response_code']==1:
	#	print "The file is a malware and %s virus engines have detected it. Detailed results found in the virustotal database are:" %response_dict['positives']
	#	for key,value in json['scans'].items():
	#		print key,value['result']
	return Ismalware,response_dict

def malware_processes_using_virustotal(config,process_list,sqlite_instance):
	try:
		virustotal_virus_process = []
		for item in process_list:
			config.logger.debug("Virustotal scan - process details - %s" %item[1])
			#check if the process exists in database - process name and md5 hash are same or changed
			process_db_check = sqlite_instance.getrow("select id from malware_process where full_path = ? and md5_hash = ?",(item[1],item[3]))
			#print process_db_check
			# check if the process is previously checked using Team Cymru malware hash registry
			cymru_process_check = sqlite_instance.getrow("select id from malware_teamcymru_scan where process_id = ?",(process_db_check))
			#print cymru_process_check
			# if the process exists, a row will be returned. If no row is returned, insert present process into the database and do malware check.
			# check team cymru malware hash repository for process hash
			#if not process_db_check:
			ismalware,response = curl_virustotal_search(item[3],config.virustotal_api_key,config.virustotal_url,config.use_proxy,config.proxy_host,config.proxy_port,config.proxy_user,config.proxy_password)
			if ismalware:
				virustotal_virus_process.append(item)
				config.logger.info("Process -%s is possibly a virus/malware. %s virus engines have detected it as virus/malware. If you wish, please re-check it using other reputed anti-virus/anti-spyware softwares."%(item[1],response_dict['positives']))
				config.logger.debug(" Virus engines and virus names for the suspicious process are listed below:")
				for key,value in response['scans'].items():
					config.logger.info("Virus-engine-%s:%s"%(key,value['result']))
			time.sleep(config.run_every_minutes*60)
	except Exception,e:
		config.logger.error("Error while processing virustotal response - %s and the error is - %s"%(response,e))

def write_malware_results(filename, cymru_process_list,virustotal_process_list):
	"""write malware results to the file"""
	with open(filename, 'w') as f:
		# process details - (pid,process,filesize,md5_result,process_path,process_name,process_state,created_on,last_modified)
		if cymru_process_list:
			f.write("As per Team Cymru's Malware Database, the following processes are found to be suspicious on your computer.\n")
			f.write("Process\tPath\t\n")
			for item in process_list:
				f.write(item[5],item[1])
		f.write('\n\n\n')
		if virustotal_process_list:
			f.write("Virustotal scan shows that the following processes are suspicious on your computer.\n")
			f.write("Process\tPath\t\n")
			for item in process_list:
				f.write(item[5],item[1])

def mail_to_admin(malware_file,config):
	import smtplib

	# Import the email modules we'll need
	from email.mime.text import MIMEText
	if os.path.isfile(malware_file) and os.path.getsize(malware_file)>=0:
		with open(malware_file, 'r') as content_file:
		    content = content_file.read()
		from_mail = config.email_user + '@' + config.email_server
		to_mail = config.email_user + '@' + config.email_server
		msg = MIMEMultipart('alternative')
		msg['Subject'] = 'Malware processes on your PC'
		#msg['From'] = from_mail
		#msg['To'] = ','.join(to_mail)
		msg['From'] = config.email_user + '@' + config.email_server
		msg['To'] = config.email_user + '@' + config.email_server
		part1 = MIMEText(content,'plain')
		#part2 = MIMEText(main_msg_html,'html')
		msg.attach(part1)
		#msg.attach(part2)
		try:
			so=smtplib.SMTP(config.email_server)
			so.docmd("AUTH LOGIN", base64.b64encode( config.email_user ))
			so.docmd(base64.b64encode( config.email_passwd ), "")
			try:
				so.sendmail(from_mail,to_mail,msg.as_string())
			finally:
				so.close()
		except Exception, e:
			config.logger.error("Unable to send E-mail that lists suspicious processes - %s"%e)

if __name__=='__main__':

	try:
		# config instance
		config = config.Config()
		sqlite_instance =  sqlite_class.Sqlite_db(config.malware_results_database)
		sqlite_instance.connection()
		#print sqlite_instance.getrow("SELECT sqlite_version()",[])
		#print sqlite_instance.getrow("PRAGMA table_info (test)",[])
		# check if PC is connected to the internet
		if not check_internet_connection(config):
			print "This program can not run as there is no internet connectivity. Kindly make sure that PC is connected to the internet and then try again."
			config.logger.error("This program can not run as there is no internet connectivity. Kindly make sure that PC is connected to the internet and then try again.")
			sys.exit(1)
		while True:
			# run every 5 minutes by default if not run_every_minute is specified in configuration file.	
			if config.run_every_minutes <1:
				config.run_every_minutes = 5
		
			process_list = []
			pids= [pid for pid in os.listdir('/proc') if pid.isdigit()]
			for pid in pids:
				if os.path.isfile('/proc/' + str(pid) +'/exe'):
					process = os.path.realpath('/proc/' + str(pid) + '/exe')
					process_path_name = os.path.split(process)
					process_path,process_name = process_path_name
					filesize=os.path.getsize('/proc/' + str(pid) + '/exe')
					md5_result = md5checksum(process,config)
					process_state = process_status(pid)
					created_on, last_modified = file_timestamps(process)
					process_list.append((pid,process,filesize,md5_result,process_path,process_name,process_state,created_on,last_modified))
			if config.use_cymru_database:
				# check if the process is malware using Team Cymru registry
				cymru_malware_processes = malware_processes_using_team_cymru(config,process_list,sqlite_instance)
				#print cymru_malware_processes
			if config.use_virustotal_database:
				# check using virustotal url
				virustotal_malware_processes = malware_processes_using_virustotal(config,process_list) 
				#print virustotal_malware_processes
			# write results to a file
			write_malware_results(config.results_file, cymru_malware_processes,virustotal_malware_processes)
			# send a E-mail
			mail_to_admin(config.results_file,config)

		sqlite_instance.disconnection()
		sys.exit(1)

	except Exception,e:
		config.logger.error("An error is encounterd during the execution of program - %s" %e)


"""
# response from Team cymru for malware entry
[psj@localhost ~]$ nslookup -querytype=TXT 733a48a9cb49651d72fe824ca91e8d00.malware.hash.cymru.com
Server:		8.8.4.4
Address:	8.8.4.4#53

Non-authoritative answer:
733a48a9cb49651d72fe824ca91e8d00.malware.hash.cymru.com	text = "1277221946 79"

Authoritative answers can be found from:

# response from Team cymru for non-malware entry
[psj@localhost ~]$ nslookup -querytype=TXT 733a48a9cb49651d72fe824ca91e8d01.malware.hash.cymru.com
Server:		8.8.4.4
Address:	8.8.4.4#53

** server can't find 733a48a9cb49651d72fe824ca91e8d01.malware.hash.cymru.com: NXDOMAIN


# response from virustotal
#{"response_code": 0, "resource": "fe387f7e606673dc94a381a1cadee59f", "verbose_msg": "The requested resource is not among the finished, queued or pending scans"}

Out[10]: '{"scans": {"TotalDefense": {"detected": true, "version": "37.0.10395", "result": "Win32/Linkbot.SC", "update": "20130426"}, "MicroWorld-eScan": {"detected": true, "version": "12.0.250.0", "result": "Trojan.Generic.1628803", "update": "20130428"}, "nProtect": {"detected": true, "version": "2013-04-27.01", "result": "Worm/W32.Kolabc.64000", "update": "20130427"}, "CAT-QuickHeal": {"detected": true, "version": "12.00", "result": "Backdoor.Nepoe.dn.n4", "update": "20130427"}, "McAfee": {"detected": true, "version": "5.400.0.1158", "result": "Downloader-BZB", "update": "20130428"}, "Malwarebytes": {"detected": true, "version": "1.75.0.1", "result": "Trojan.Downloader", "update": "20130427"}, "K7AntiVirus": {"detected": true, "version": "9.166.8590", "result": "Riskware", "update": "20130426"}, "K7GW": {"detected": false, "version": "12.7.0.12", "result": null, "update": "20130426"}, "TheHacker": {"detected": true, "version": "None", "result": "W32/Kolabc.bnj", "update": "20130426"}, "NANO-Antivirus": {"detected": true, "version": "0.24.0.52214", "result": "Trojan.Win32.Sdbot.begsyp", "update": "20130427"}, "F-Prot": {"detected": true, "version": "4.7.1.166", "result": "W32/Worm.NMT", "update": "20130427"}, "Symantec": {"detected": true, "version": "20121.3.0.76", "result": "W32.Spybot.Worm", "update": "20130427"}, "Norman": {"detected": true, "version": "7.01.04", "result": "Suspicious_Gen3.VGAD", "update": "20130426"}, "ByteHero": {"detected": false, "version": "1.0.0.1", "result": null, "update": "20130426"}, "TrendMicro-HouseCall": {"detected": true, "version": "9.700.0.1001", "result": "WORM_POEBOT.AKE", "update": "20130428"}, "Avast": {"detected": true, "version": "6.0.1289.0", "result": "Win32:Nepoe-K [Trj]", "update": "20130428"}, "eSafe": {"detected": true, "version": "7.0.17.0", "result": "Win32.Kolabc.bnj", "update": "20130423"}, "ClamAV": {"detected": false, "version": "0.97.3.0", "result": null, "update": "20130427"}, "Kaspersky": {"detected": true, "version": "9.0.0.837", "result": "Backdoor.Win32.Nepoe.dn", "update": "20130428"}, "BitDefender": {"detected": true, "version": "7.2", "result": "Trojan.Generic.1628803", "update": "20130428"}, "Agnitum": {"detected": true, "version": "5.5.1.3", "result": "Worm.Kolabc!JQO7hizifwc", "update": "20130427"}, "ViRobot": {"detected": true, "version": "2011.4.7.4223", "result": "Worm.Win32.Net-Kolabc.64000", "update": "20130427"}, "Sophos": {"detected": true, "version": "4.88.0", "result": "Mal/Generic-S", "update": "20130427"}, "Comodo": {"detected": true, "version": "16085", "result": "TrojWare.Win32.Trojan.NSPM.~gen", "update": "20130427"}, "F-Secure": {"detected": true, "version": "11.0.19020.35", "result": "Trojan.Generic.1628803", "update": "20130428"}, "DrWeb": {"detected": true, "version": "", "result": "BackDoor.IRC.Sdbot.2665", "update": "20130428"}, "VIPRE": {"detected": true, "version": "17244", "result": "Trojan.Win32.Ircbot!cobra (v)", "update": "20130428"}, "AntiVir": {"detected": true, "version": "7.11.74.166", "result": "TR/Crypt.NSPM.Gen", "update": "20130427"}, "TrendMicro": {"detected": true, "version": "9.740.0.1012", "result": "WORM_POEBOT.AKE", "update": "20130427"}, "McAfee-GW-Edition": {"detected": true, "version": "2012.1", "result": "Heuristic.LooksLike.Win32.Suspicious.C", "update": "20130427"}, "Emsisoft": {"detected": true, "version": "3.0.0.575", "result": "Trojan.Generic.1628803 (B)", "update": "20130428"}, "Jiangmin": {"detected": true, "version": "16.0.100", "result": "Net-Worm.Kolabc.hx", "update": "20130427"}, "Antiy-AVL": {"detected": false, "version": "2.0.3.7", "result": null, "update": "20130427"}, "Kingsoft": {"detected": true, "version": "2013.4.9.267", "result": "Win32.Hack.Nepoe.dn.(kcloud)", "update": "20130422"}, "Microsoft": {"detected": true, "version": "1.9402", "result": "Backdoor:Win32/Poebot.gen", "update": "20130428"}, "SUPERAntiSpyware": {"detected": false, "version": "5.6.0.1008", "result": null, "update": "20130427"}, "GData": {"detected": true, "version": "22", "result": "Trojan.Generic.1628803", "update": "20130428"}, "Commtouch": {"detected": false, "version": "5.4.1.7", "result": null, "update": "20130427"}, "AhnLab-V3": {"detected": true, "version": "2013.04.28.00", "result": "Win32/Kolabc.worm.64000", "update": "20130427"}, "VBA32": {"detected": true, "version": "3.12.20.2", "result": "Backdoor.VanBot", "update": "20130427"}, "PCTools": {"detected": true, "version": "9.0.0.2", "result": "Backdoor.Nepoe", "update": "20130427"}, "ESET-NOD32": {"detected": true, "version": "8274", "result": "Win32/Poebot", "update": "20130427"}, "Ikarus": {"detected": true, "version": "T3.1.4.0.0", "result": "Trojan-Downloader.Win32.Banload", "update": "20130427"}, "Fortinet": {"detected": false, "version": "5.0.43.0", "result": null, "update": "20130428"}, "AVG": {"detected": true, "version": "10.0.0.1190", "result": "BackDoor.RBot.KB", "update": "20130427"}, "Panda": {"detected": true, "version": "10.0.3.5", "result": "W32/Kolabc.Q.worm", "update": "20130427"}}, "scan_id": "b018706f57937136a2f61421c5a7a9f4ce8c89c3670ae4814491473184545962-1367105107", "sha1": "5b63d3bf46aec2126932d8a683ca971c56f7d717", "resource": "cbed16069043a0bf3c92fff9a99cccdc", "response_code": 1, "scan_date": "2013-04-27 23:25:07", "permalink": "https://www.virustotal.com/file/b018706f57937136a2f61421c5a7a9f4ce8c89c3670ae4814491473184545962/analysis/1367105107/", "verbose_msg": "Scan finished, scan information embedded in this object", "total": 46, "positives": 39, "sha256": "b018706f57937136a2f61421c5a7a9f4ce8c89c3670ae4814491473184545962", "md5": "cbed16069043a0bf3c92fff9a99cccdc"}'

{'md5': 'cbed16069043a0bf3c92fff9a99cccdc',
 'permalink': 'https://www.virustotal.com/file/b018706f57937136a2f61421c5a7a9f4ce8c89c3670ae4814491473184545962/analysis/1367105107/',
 'positives': 39,
 'resource': 'cbed16069043a0bf3c92fff9a99cccdc',
 'response_code': 1,
 'scan_date': '2013-04-27 23:25:07',
 'scan_id': 'b018706f57937136a2f61421c5a7a9f4ce8c89c3670ae4814491473184545962-1367105107',
 'scans': {'AVG': {'detected': True,
   'result': 'BackDoor.RBot.KB',
   'update': '20130427',
   'version': '10.0.0.1190'},
  'Agnitum': {'detected': True,
   'result': 'Worm.Kolabc!JQO7hizifwc',
   'update': '20130427',
   'version': '5.5.1.3'},
  'AhnLab-V3': {'detected': True,
   'result': 'Win32/Kolabc.worm.64000',
   'update': '20130427',
   'version': '2013.04.28.00'},
  'AntiVir': {'detected': True,
   'result': 'TR/Crypt.NSPM.Gen',
   'update': '20130427',
   'version': '7.11.74.166'},
  'Antiy-AVL': {'detected': False,
   'result': None,
   'update': '20130427',
   'version': '2.0.3.7'},
  'Avast': {'detected': True,
   'result': 'Win32:Nepoe-K [Trj]',
   'update': '20130428',
   'version': '6.0.1289.0'},
  'BitDefender': {'detected': True,
   'result': 'Trojan.Generic.1628803',
   'update': '20130428',
   'version': '7.2'},
  'ByteHero': {'detected': False,
   'result': None,
   'update': '20130426',
   'version': '1.0.0.1'},
  'CAT-QuickHeal': {'detected': True,
   'result': 'Backdoor.Nepoe.dn.n4',
   'update': '20130427',
   'version': '12.00'},
  'ClamAV': {'detected': False,
   'result': None,
   'update': '20130427',
   'version': '0.97.3.0'},
  'Commtouch': {'detected': False,
   'result': None,
   'update': '20130427',
   'version': '5.4.1.7'},
  'Comodo': {'detected': True,
   'result': 'TrojWare.Win32.Trojan.NSPM.~gen',
   'update': '20130427',
   'version': '16085'},
  'DrWeb': {'detected': True,
   'result': 'BackDoor.IRC.Sdbot.2665',
   'update': '20130428',
   'version': u''},
  'ESET-NOD32': {'detected': True,
   'result': 'Win32/Poebot',
   'update': '20130427',
   'version': '8274'},
  'Emsisoft': {'detected': True,
   'result': 'Trojan.Generic.1628803 (B)',
   'update': '20130428',
   'version': '3.0.0.575'},
  'F-Prot': {'detected': True,
   'result': 'W32/Worm.NMT',
   'update': '20130427',
   'version': '4.7.1.166'},
  'F-Secure': {'detected': True,
   'result': 'Trojan.Generic.1628803',
   'update': '20130428',
   'version': '11.0.19020.35'},
  'Fortinet': {'detected': False,
   'result': None,
   'update': '20130428',
   'version': '5.0.43.0'},
  'GData': {'detected': True,
   'result': 'Trojan.Generic.1628803',
   'update': '20130428',
   'version': '22'},
  'Ikarus': {'detected': True,
   'result': 'Trojan-Downloader.Win32.Banload',
   'update': '20130427',
   'version': 'T3.1.4.0.0'},
  'Jiangmin': {'detected': True,
   'result': 'Net-Worm.Kolabc.hx',
   'update': '20130427',
   'version': '16.0.100'},
  'K7AntiVirus': {'detected': True,
   'result': 'Riskware',
   'update': '20130426',
   'version': '9.166.8590'},
  'K7GW': {'detected': False,
   'result': None,
   'update': '20130426',
   'version': '12.7.0.12'},
  'Kaspersky': {'detected': True,
   'result': 'Backdoor.Win32.Nepoe.dn',
   'update': '20130428',
   'version': '9.0.0.837'},
  'Kingsoft': {'detected': True,
   'result': 'Win32.Hack.Nepoe.dn.(kcloud)',
   'update': '20130422',
   'version': '2013.4.9.267'},
  'Malwarebytes': {'detected': True,
   'result': 'Trojan.Downloader',
   'update': '20130427',
   'version': '1.75.0.1'},
  'McAfee': {'detected': True,
   'result': 'Downloader-BZB',
   'update': '20130428',
   'version': '5.400.0.1158'},
  'McAfee-GW-Edition': {'detected': True,
   'result': 'Heuristic.LooksLike.Win32.Suspicious.C',
   'update': '20130427',
   'version': '2012.1'},
  'MicroWorld-eScan': {'detected': True,
   'result': 'Trojan.Generic.1628803',
   'update': '20130428',
   'version': '12.0.250.0'},
  'Microsoft': {'detected': True,
   'result': 'Backdoor:Win32/Poebot.gen',
   'update': '20130428',
   'version': '1.9402'},
  'NANO-Antivirus': {'detected': True,
   'result': 'Trojan.Win32.Sdbot.begsyp',
   'update': '20130427',
   'version': '0.24.0.52214'},
  'Norman': {'detected': True,
   'result': 'Suspicious_Gen3.VGAD',
   'update': '20130426',
   'version': '7.01.04'},
  'PCTools': {'detected': True,
   'result': 'Backdoor.Nepoe',
   'update': '20130427',
   'version': '9.0.0.2'},
  'Panda': {'detected': True,
   'result': 'W32/Kolabc.Q.worm',
   'update': '20130427',
   'version': '10.0.3.5'},
  'SUPERAntiSpyware': {'detected': False,
   'result': None,
   'update': '20130427',
   'version': '5.6.0.1008'},
  'Sophos': {'detected': True,
   'result': 'Mal/Generic-S',
   'update': '20130427',
   'version': '4.88.0'},
  'Symantec': {'detected': True,
   'result': 'W32.Spybot.Worm',
   'update': '20130427',
   'version': '20121.3.0.76'},
  'TheHacker': {'detected': True,
   'result': 'W32/Kolabc.bnj',
   'update': '20130426',
   'version': 'None'},
  'TotalDefense': {'detected': True,
   'result': 'Win32/Linkbot.SC',
   'update': '20130426',
   'version': '37.0.10395'},
  'TrendMicro': {'detected': True,
   'result': 'WORM_POEBOT.AKE',
   'update': '20130427',
   'version': '9.740.0.1012'},
  'TrendMicro-HouseCall': {'detected': True,
   'result': 'WORM_POEBOT.AKE',
   'update': '20130428',
   'version': '9.700.0.1001'},
  'VBA32': {'detected': True,
   'result': 'Backdoor.VanBot',
   'update': '20130427',
   'version': '3.12.20.2'},
  'VIPRE': {'detected': True,
   'result': 'Trojan.Win32.Ircbot!cobra (v)',
   'update': '20130428',
   'version': '17244'},
  'ViRobot': {'detected': True,
   'result': 'Worm.Win32.Net-Kolabc.64000',
   'update': '20130427',
   'version': '2011.4.7.4223'},
  'eSafe': {'detected': True,
   'result': 'Win32.Kolabc.bnj',
   'update': '20130423',
   'version': '7.0.17.0'},
  'nProtect': {'detected': True,
   'result': 'Worm/W32.Kolabc.64000',
   'update': '20130427',
   'version': '2013-04-27.01'}},
 'sha1': '5b63d3bf46aec2126932d8a683ca971c56f7d717',
 'sha256': 'b018706f57937136a2f61421c5a7a9f4ce8c89c3670ae4814491473184545962',
 'total': 46,
 'verbose_msg': 'Scan finished, scan information embedded in this object'}
"""
